grammar Roller;

@parser::header {
package com.braincasedesigns.roller.parser.generated;
import com.braincasedesigns.roller.parser.model.*;
}

@lexer::header {
package com.braincasedesigns.roller.parser.generated;
}

rolls returns [List<RollDescription> rolls = new ArrayList<RollDescription>()]
	:	 (d=repeatedDieRoll{$rolls.add(d);} seperator*)* EOF;
	
    
repeatedDieRoll	returns [RollDescription roll = new RollDescription()]:
	( rep=number LPAREN) rd=dieRoll { $roll = rd; $roll.setRepeat(rep);} (RPAREN)
	  
		|  d=dieRoll {$roll = d;} ;
		

    
dieRoll	returns [RollDescription roll = new RollDescription()]:
	num=number {$roll.setNumberOfDice(num);} face=die {$roll.setFaces(face);} mod=modifier* {$roll.setModifier(mod);};
	

seperator
	:	WS* (SEMI|NEWLINE);



die	returns [String faces = null]:	DEE ( val=number {$faces =String.valueOf(val);} | s=facesString {$faces = s;})  ;

facesString returns [String value = null]
	:	val = ('F'|'f'|'%') {$value=val.getText();};
//faces:	(NON_ZERO|'F');

modifier returns [Modifier mod = null]:
op=operator
num=number
{ $mod = new Modifier(op, num);}
;

operator returns [String value= null]:
	(
	PLUS {$value=$PLUS.getText();} |
	MINUS {$value=$MINUS.getText();} |
	MULTIPLY {$value=$MULTIPLY.getText();}
	);

number returns [int value]
: NON_ZERO {$value = Integer.parseInt($NON_ZERO.text);};


//Parser rules

SEMI	:	';'; //{newline()};

DEE	:	('d'|'D');


PLUS	:	'+';
MINUS	: 	'-';
MULTIPLY:	'*';

LPAREN	:	 '(';
RPAREN  :	')';


NON_ZERO:	'1'..'9' ('0'..'9')*;

NEWLINE : ('\r''\n')=> '\r''\n' //DOS
        | '\r'                  //MAC
        | '\n'                  //UNIX
        //{ System.out.println("matched newline"); newline(); }
        ;
WS      : (' '|'\t')+ { $channel = HIDDEN; } ;
